﻿///////////////////////////////////////////////////////////////////////////////
// File:        Worker.cc
// Author:      671643387@qq.com
// Description:
///////////////////////////////////////////////////////////////////////////////


#include <boost/bind.hpp>
#include "Summary.hpp"

#include "Worker.hpp"

Worker::Worker()
: clientIdGen_(0)
, loop_()
, clients_()
{

}

Worker::~Worker()
{
    doClear();
}

bool Worker::open(std::string addr, int port, unsigned int bufSize, int clients, std::string message)
{
    for (int x=0; x < clients; ++x)
    {
        ClientPtr client(new Client(loop_));
        if (client->open(addr, port, bufSize, message))
        {
            int clientId = ++clientIdGen_;
            client->setId(clientId);
            client->setCloseFN(boost::bind(&Worker::closeClient, this, _1));
            clients_[clientId] = client;
            gSummary.inc_ConnLoad();
        }
    }

    return true;
}

void Worker::run()
{
    loop_.run();
}

void Worker::stop()
{
    loop_.queue(boost::bind(&Worker::doStop, this));
}

void Worker::closeClient(int id)
{
    loop_.queue(boost::bind(&Worker::doCloseClient, this, id));
}

void Worker::doCloseClient(int id)
{
    ClientMap::iterator it = clients_.find(id);
    if (it != clients_.end())
    {
        loop_.getReactor()->removeSource(
            it->second->getSocket().getSOCKET());
        clients_.erase(it);
        gSummary.dec_ConnLoad();
    }
}

void Worker::doStop()
{
    doClear();
    loop_.stop();
}


void Worker::doClear()
{
    if (!clients_.empty())
    {
        ClientMap::iterator it = clients_.begin();
        ClientMap::iterator end = clients_.end();

        for (; it != end; ++it)
        {
            loop_.getReactor()->removeSource(
                it->second->getSocket().getSOCKET());
            gSummary.dec_ConnLoad();
        }
        clients_.clear();
    }
}